// SPDX-License-Identifier: GPL-2.0-or-later
// Copyright (c) 2023 Yevhen Babiichuk (DustDFG)

#include <Abracadabra/View/Tube.hpp>

namespace View
{

Tube::Tube(uint8_t size, sf::FloatRect boundsRect, Theme* theme)
	: size(size)
	, boundsRect(boundsRect)
	, theme(theme)
	, dots(size, sf::RectangleShape())
	, tube(size, sf::RectangleShape())
	, selectedTube(size, sf::RectangleShape())
{
	float width = boundsRect.width;
	float height = boundsRect.height / this->size;

	for(uint8_t i = 0; i < this->size; ++i)
	{
		//Dots initialization
		this->dots[i].setSize({width, height});
		this->dots[i].setPosition({boundsRect.left, boundsRect.top + (height * i)});
		this->dots[i].setTexture(&this->theme->dotsTexture);


		//Tube initialization
		this->tube[i].setSize({width, height});
		this->tube[i].setPosition({boundsRect.left, boundsRect.top + (height * i)});
		this->tube[i].setTexture(&this->theme->tubeTexture);

		this->selectedTube[i].setSize({width, height});
		this->selectedTube[i].setPosition({boundsRect.left, boundsRect.top + (height * i)});
		this->selectedTube[i].setTexture(&this->theme->selectedTubeTexture);

		if(i == 0)
		{
			this->tube[i].setTextureRect({0, this->theme->tubePartTextureH * 0, this->theme->tubePartTextureW, this->theme->tubePartTextureH});
			this->selectedTube[i].setTextureRect({0, this->theme->tubePartTextureH * 0, this->theme->tubePartTextureW, this->theme->tubePartTextureH});
		}
		else if(i == this->size - 1)
		{
			this->tube[i].setTextureRect({0, this->theme->tubePartTextureH * 2, this->theme->tubePartTextureW, this->theme->tubePartTextureH});
			this->selectedTube[i].setTextureRect({0, this->theme->tubePartTextureH * 2, this->theme->tubePartTextureW, this->theme->tubePartTextureH});
		}
		else
		{
			this->tube[i].setTextureRect({0, this->theme->tubePartTextureH * 1, this->theme->tubePartTextureW, this->theme->tubePartTextureH});
			this->selectedTube[i].setTextureRect({0, this->theme->tubePartTextureH * 1, this->theme->tubePartTextureW, this->theme->tubePartTextureH});
		}
	}
}

void Tube::drawDots(sf::RenderTarget& target) const
{
	for(uint8_t i = 0; i < this->size; ++i)
	{
		target.draw(this->dots[i]);
	}
}

void Tube::drawTube(sf::RenderTarget& target) const
{
	for(uint8_t i = 0; i < this->size; ++i)
	{
		target.draw(this->tube[i]);
	}
}

void Tube::drawSelectedTube(sf::RenderTarget& target) const
{
	for(uint8_t i = 0; i < this->size; ++i)
	{
		target.draw(this->selectedTube[i]);
	}
}

void Tube::update(const std::vector<uint8_t>& dots)
{
	for(uint8_t i = 0; i < this->size; ++i)
	{
		if(dots.size() <= i)
		{
			this->dots[this->size - 1 - i].setTextureRect({0, 0, 0, 0});
		}
		else
		{
			this->dots[this->size - 1 - i].setTextureRect({this->theme->dotTextureW * dots[i], 0, this->theme->dotTextureW, this->theme->dotTextureH});
		}
	}
}

bool Tube::contains(sf::Vector2f position)
{
	return this->boundsRect.contains(position);
}

sf::FloatRect Tube::getSlotRect(uint8_t slotIndex) const
{
	sf::FloatRect rect;

	rect.width = this->boundsRect.width;
	rect.height = (this->boundsRect.height / this->size);

	rect.top = (this->boundsRect.top + this->boundsRect.height) - (rect.height * slotIndex);
	rect.left = this->boundsRect.left;

	return rect;
}

sf::FloatRect Tube::getOverflowRect() const
{
	sf::FloatRect rect;

	rect.width = this->boundsRect.width;
	rect.height = (this->boundsRect.height / this->size);

	rect.top = this->boundsRect.top - rect.height;
	rect.left = this->boundsRect.left;

	return rect;
}

}
